#include "BrushGuide.h"
#include "Character/monster/MonsterMgr.h"
#include "Character/monster/MonsterRefCfg.h"
#include "Duplicate/IDuplicate.h"
#include "Character/CreatureMgr.h"
#include "Character/newAI/behaviac/CreatureCommonAI.h"

BrushGuide::BrushGuide() :m_pDuplicate(nullptr), m_pBrush(nullptr)
{
	m_bBrushFinish = false;
	m_bStart = false;
	m_setGuideGroup.clear();
}

BrushGuide::~BrushGuide()
{
	
}

bool BrushGuide::Init(IDuplicate *pDuplicate)
{
	if (nullptr == pDuplicate)
	{
		LogErrFmtPrint("BrushGuide::Init...nullptr == pDuplicate");
		return false;
	}
	m_pDuplicate = pDuplicate;
	AllBrushDataCfg *pAllBrush = m_pDuplicate->GetBrushData();
	if (nullptr == pAllBrush)
	{
		LogErrFmtPrint("BrushGuide::Init...nullptr == pAllBrush...sceneid:%u,dupid:%u ",pDuplicate->GetSceneID(),pDuplicate->GetDuplicateID());
		return false;
	}
	m_pBrush = &pAllBrush->stNew;

	//初始禁用所有的区域刷新的NPC
	DisableNpc(m_pBrush->setAllAreaNpc);

	return true;
}

void BrushGuide::UnInit()
{
	g_GetTimerAxis()->KillAllTimer(this);
	m_pDuplicate = nullptr;
	m_pBrush = nullptr;
	m_bStart = false;
	m_bBrushFinish = false;
	m_setGuideGroup.clear();
}
void BrushGuide::StartBrush()
{
	m_bStart = true;
}

void BrushGuide::StopBrush()
{
	m_bStart = false;
	m_bBrushFinish = true;
	g_GetTimerAxis()->KillAllTimer(this);
}

//是否刷怪完成
bool BrushGuide::FinishBrush()
{
	return m_bBrushFinish;
}

void BrushGuide::BrushUpdate()
{
	if (m_bBrushFinish)
		return;;
	if (m_pBrush->brushFinish())
		m_bBrushFinish = true;
}
void BrushGuide::OnMonterDead(uint64_t monsCid, uint32_t monsId, uint32_t count, int32_t formationId, uint64_t killerCid)
{
	if (nullptr == m_pDuplicate)
	{
		LogErrFmtPrint("[logic] BrushGuide::OnMonterDead....nullptr == m_pDuplicate....monsCid:%lu, monsId:%u, count:%u, formationId:%u,killercid:%lu ", monsCid, monsId, count, formationId, killerCid);
		return;
	}
	if (nullptr == m_pBrush)
	{
		LogErrFmtPrint("[logic] BrushGuide::OnMonterDead....nullptr == m_pBrush....monsCid:%lu, monsId:%u, count:%u, formationId:%u,killercid:%lu ", monsCid, monsId, count, formationId,killerCid);
		return;
	}	
	int32_t stepIdx = m_pDuplicate->GetCurGuideIdx();
	if (stepIdx < 0 || stepIdx >= (int32_t)m_pBrush->vecNewStep.size())
	{
		LogErrFmtPrint("[logic] BrushGuide::OnMonterDead....m_stepIdx < 0 || m_stepIdx >= m_pBrush->vecNewStep.size()....monsCid:%lu, monsId:%u, count:%u, formationId:%u,killercid:%lu,stepidx:%d,size:%d ", monsCid, monsId, count, formationId, killerCid, stepIdx, m_pBrush->vecNewStep.size());
		return;
	}
	//LogDebugFmtPrint("[logic] BrushCommon::OnMonterDead....monsCid:%lu, monsId:%u, count:%u, formationId:%u ",monsCid, monsId,count,formationId);
	//是否是编队怪，是否有死亡刷新
	if (formationId > 0)
	{
		NewStepCfgInfo &stepCfg = m_pBrush->vecNewStep.at(stepIdx);
		//有编队的怪
		VecMonsDieNpcDieCfg::iterator iterDie = stepCfg.vecMonsDieNpcDie.begin();
		while (iterDie != stepCfg.vecMonsDieNpcDie.end())
		{
			NewMonsDieNpcDieCfgInfo &stDieCfg = (*iterDie);
			if (0 == stDieCfg.setDie.size())
			{
				iterDie = stepCfg.vecMonsDieNpcDie.erase(iterDie);
				continue;
			}
			SET_UINT32::iterator iterSet = stDieCfg.setDie.find(formationId);
			if (iterSet == stDieCfg.setDie.end())
			{
				++iterDie;
				continue;
			}
			MAP_UINT32_UINT32::iterator iterMon = stDieCfg.mapDieMonster.find(monsId);
			if (iterMon == stDieCfg.mapDieMonster.end())
			{
				++iterDie;
				continue;
			}
			if (iterMon->second >= count)
			{
				iterMon->second -= count;
			}
			else
			{
				iterMon->second = 0;
			}
			//
			if (iterMon->second > 0)
			{
				++iterDie;
				continue;
			}
			stDieCfg.mapDieMonster.erase(iterMon);
			if (stDieCfg.mapDieMonster.size() > 0)
			{
				++iterDie;
				continue;
			}
			//所有指定编队的怪物全部死亡了,NPC死亡
			NpcDie(stDieCfg.setDieNpc);
			iterDie = stepCfg.vecMonsDieNpcDie.erase(iterDie);
		}
	}
}

//区域刷怪
bool BrushGuide::EnterAreaBrush(uint32_t areaId)
{
	if (nullptr == m_pDuplicate)
	{
		LogErrFmtPrint("[logic] BrushGuide::EnterAreaBrush....nullptr == m_pDuplicate....areaId:%u ", areaId);
		return false;
	}
	if (nullptr == m_pBrush)
	{
		LogErrFmtPrint("[logic] BrushGuide::EnterAreaBrush....nullptr == m_pBrush....areaId:%u , dupid:%u, sceneid:%u ", areaId, m_pDuplicate->GetDuplicateID(), m_pDuplicate->GetSceneID());
		return false;
	}
	
	int32_t stepIdx = m_pDuplicate->GetCurGuideIdx();
	if (stepIdx < 0 || stepIdx >= (int32_t)m_pBrush->vecNewStep.size())
	{
		LogErrFmtPrint("[logic] BrushGuide::EnterAreaBrush....m_stepIdx < 0 || m_stepIdx >= m_pBrush->vecNewStep.size()....areaId:%u , dupid:%u, sceneid:%u ,stepidx:%d,size:%d ", areaId, m_pDuplicate->GetDuplicateID(), m_pDuplicate->GetSceneID(), stepIdx, m_pBrush->vecNewStep.size());
		return false;
	}
	LogDebugFmtPrint("[logic] BrushGuide::EnterAreaBrush....areaId:%u , dupid:%u, sceneid:%u,stepidx:%d ", areaId, m_pDuplicate->GetDuplicateID(), m_pDuplicate->GetSceneID(), stepIdx);

	NewStepCfgInfo &stepCfg = m_pBrush->vecNewStep.at(stepIdx);

	//进入区域刷怪
	MAP_UINT32_VEC_UINT32::iterator iter = stepCfg.mapVecEnterArea.find(areaId);
	if (iter != stepCfg.mapVecEnterArea.end())
	{
		VEC_UINT32 &vecBrushTid = iter->second;
		VEC_UINT32::iterator iterTid = vecBrushTid.begin();
		for (; iterTid != vecBrushTid.end(); ++iterTid)
		{
			//这里按照怪物编队ID刷怪
			uint32_t nGroupId = (*iterTid);
			const std::vector<MonsterRefLocation>* pMonsterRefCfg = g_GetMapLocationCfg()->GetMapGroupMonster(m_pDuplicate->GetMapID(), nGroupId);
			if (nullptr == pMonsterRefCfg)
			{
				continue;
			}
			std::vector<MonsterRefLocation>::const_iterator iterRef = pMonsterRefCfg->begin();
			for (; iterRef != pMonsterRefCfg->end(); ++iterRef)
			{
				const MonsterRefLocation &stMonCfg = (*iterRef);
				Point3<float> curDir = Point3<float>(0, 0, 1);
				if (stMonCfg.m_dir != Point3<float>())
				{
					float rad = AngleToRadian(stMonCfg.m_dir.y);
					float x = sin(rad);
					float z = cos(rad);
					Point3<float> dir = Point3<float>(x, 0, z);
					float length = dir.length();
					if (length != 0)
					{
						curDir = dir / length;
					}
				}
				MonsCreateParam createParam;
				createParam.createType = EMonsCreateType_Dup;
				createParam.createTypeVal = m_pDuplicate->GetDuplicateID();
				Monster *pMonster = g_GetCreatureMgr()->CreateMonster(stMonCfg.m_id, m_pDuplicate->GetSceneID(), stMonCfg.m_bornPos, createParam, curDir, stMonCfg.m_RefLocIndex, nullptr, 0, stMonCfg.m_group);
				if (nullptr != pMonster)
				{
					//设置编队
					pMonster->SetFormationId(nGroupId);

					LogDebugFmtPrint("[logic] BrushGuide::EnterAreaBrush....areaId:%u ,nGroupId:%u,monsid:%u,cid:%llu, dupid:%u, sceneid:%u,stepidx:%d ", areaId, nGroupId, stMonCfg.m_id, pMonster->GetCid(), m_pDuplicate->GetDuplicateID(), m_pDuplicate->GetSceneID(), stepIdx);
				}
			}
		} // end of for (; iterTid != vecBrushTid.end(); ++iterTid)

		stepCfg.mapVecEnterArea.erase(iter);
	}
	
	//进入区域刷NPC
	MAP_UINT32_SET_UINT32::iterator iterA = stepCfg.mapNpcEnterArea.find(areaId);
	if (iterA != stepCfg.mapNpcEnterArea.end())
	{
		EnableNpc(iterA->second);
		stepCfg.mapNpcEnterArea.erase(iterA);
	}

	return true;
}


//刷新步骤引导和特效怪物组
void BrushGuide::BrushGuideMonsGroup()
{
	if (nullptr == m_pDuplicate)
	{
		LogErrFmtPrint("[logic] BrushGuide::BrushGuideMonsGroup....nullptr == m_pDuplicate....");
		return;
	}
	if (nullptr == m_pBrush)
	{
		LogErrFmtPrint("[logic] BrushGuide::BrushGuideMonsGroup....nullptr == m_pBrush....dupid:%u, sceneid:%u ", m_pDuplicate->GetDuplicateID(), m_pDuplicate->GetSceneID());
		return;
	}
	int32_t stepidx = m_pDuplicate->GetCurGuideIdx();
	uint32_t sceneId = m_pDuplicate->GetSceneID();
	Scene *pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (nullptr == pScene)
	{
		LogErrFmtPrint("BrushGuide::BrushGuideMonsGroup...nullptr == pScene...dupid:%u,scene:%u,mapid:%u,stepidx:%d ", m_pDuplicate->GetDuplicateID(), m_pDuplicate->GetSceneID(), m_pDuplicate->GetMapID(), m_pDuplicate->GetCurGuideIdx());
		return;
	}
	//先移除旧步骤刷新出来的引导和特效怪物
	SET_UINT64::iterator iter = m_setGuideGroup.begin();
	for (; iter != m_setGuideGroup.end(); ++iter)
	{
		Monster *pMonster = pScene->GetMonster((*iter));
		if (nullptr != pMonster)
		{
			if (pMonster->LeaveScene())
			{
				g_GetCreatureMgr()->WaitDestory(pMonster);
			}
		}
	}

	//再刷新新的步骤的引导和特效怪
	if (stepidx >= 0 && stepidx < (int32_t)m_pBrush->vecNewStep.size())
	{
		NewStepCfgInfo &info = m_pBrush->vecNewStep.at(stepidx);
		SET_UINT32::const_iterator iterTid = info.setGuideMonsGroup.begin();
		for (; iterTid != info.setGuideMonsGroup.end(); ++iterTid)
		{
			uint32_t nGroupId = (*iterTid);
			const std::vector<MonsterRefLocation>* pMonsterRefCfg = g_GetMapLocationCfg()->GetMapGroupMonster(m_pDuplicate->GetMapID(), nGroupId);
			if (nullptr == pMonsterRefCfg)
			{
				continue;
			}
			std::vector<MonsterRefLocation>::const_iterator iterRef = pMonsterRefCfg->begin();
			for (; iterRef != pMonsterRefCfg->end(); ++iterRef)
			{
				const MonsterRefLocation &stMonCfg = (*iterRef);
				Point3<float> curDir = Point3<float>(0, 0, 1);
				if (stMonCfg.m_dir != Point3<float>())
				{
					float rad = AngleToRadian(stMonCfg.m_dir.y);
					float x = sin(rad);
					float z = cos(rad);
					Point3<float> dir = Point3<float>(x, 0, z);
					float length = dir.length();
					if (length != 0)
					{
						curDir = dir / length;
					}
				}
				MonsCreateParam createParam;
				createParam.createType = EMonsCreateType_Dup;
				createParam.createTypeVal = m_pDuplicate->GetDuplicateID();
				Monster *pMonster = g_GetCreatureMgr()->CreateMonster(stMonCfg.m_id, m_pDuplicate->GetSceneID(), stMonCfg.m_bornPos, createParam, curDir, stMonCfg.m_RefLocIndex, nullptr, 0, stMonCfg.m_group);
				if (nullptr != pMonster)
				{
					//设置编队
					pMonster->SetFormationId(nGroupId);
					m_setGuideGroup.insert(pMonster->GetCid());
					LogDebugFmtPrint("[logic] BrushGuide::BrushGuideMonsGroup....nGroupId:%u,monsid:%u,cid:%llu, dupid:%u, sceneid:%u,stepidx:%d ", nGroupId, stMonCfg.m_id, pMonster->GetCid(), m_pDuplicate->GetDuplicateID(), m_pDuplicate->GetSceneID(), stepidx);
				}
			}
		}
	}
}


//初始化步骤引导和特效怪物组
void BrushGuide::InitGuideMonsGroup()
{
	if (nullptr == m_pDuplicate)
	{
		LogErrFmtPrint("BrushGuide::InitGuideMonsGroup...nullptr == m_pDuplicate");
		return;
	}
	int32_t stepidx = m_pDuplicate->GetCurGuideIdx();
	if (nullptr == m_pBrush)
	{
		LogErrFmtPrint("BrushGuide::InitGuideMonsGroup...nullptr == m_pBrush  dup:%u,scene:%u,map:%u ,stepidx:%d",m_pDuplicate->GetDuplicateID(),m_pDuplicate->GetSceneID(),m_pDuplicate->GetMapID(),stepidx);
		return;
	}
	if (stepidx < 0 || stepidx >= (int32_t)m_pBrush->vecNewStep.size())
	{
		LogErrFmtPrint("BrushGuide::InitGuideMonsGroup...stepidx < 0 || stepidx >= (int32_t)m_pBrush->vecNewStep.size()  dup:%u,scene:%u,map:%u ,stepidx:%d,isize:%d ", m_pDuplicate->GetDuplicateID(), m_pDuplicate->GetSceneID(), m_pDuplicate->GetMapID(), stepidx, (int32_t)m_pBrush->vecNewStep.size());
		return;
	}
	NewStepCfgInfo &info = m_pBrush->vecNewStep.at(stepidx);
	SET_UINT32::const_iterator iter = info.setGuideMonsGroup.begin();
	for (; iter != info.setGuideMonsGroup.end(); ++iter)
	{
		uint32_t nGroupId = (*iter);
		const std::vector<MonsterRefLocation>* pMonsterRefCfg = g_GetMapLocationCfg()->GetMapGroupMonster(m_pDuplicate->GetMapID(), nGroupId);
		if (nullptr == pMonsterRefCfg)
		{
			continue;
		}
		std::vector<MonsterRefLocation>::const_iterator iterRef = pMonsterRefCfg->begin();
		for (; iterRef != pMonsterRefCfg->end(); ++iterRef)
		{
			const MonsterRefLocation &stMonCfg = (*iterRef);
			Point3<float> curDir = Point3<float>(0, 0, 1);
			if (stMonCfg.m_dir != Point3<float>())
			{
				float rad = AngleToRadian(stMonCfg.m_dir.y);
				float x = sin(rad);
				float z = cos(rad);
				Point3<float> dir = Point3<float>(x, 0, z);
				float length = dir.length();
				if (length != 0)
				{
					curDir = dir / length;
				}
			}
			MonsCreateParam createParam;
			createParam.createType = EMonsCreateType_Dup;
			createParam.createTypeVal = m_pDuplicate->GetDuplicateID();
			Monster *pMonster = g_GetCreatureMgr()->CreateMonster(stMonCfg.m_id, m_pDuplicate->GetSceneID(), stMonCfg.m_bornPos, createParam, curDir, stMonCfg.m_RefLocIndex, nullptr, 0, stMonCfg.m_group);
			if (nullptr != pMonster)
			{
				//设置编队
				pMonster->SetFormationId(nGroupId);
				m_setGuideGroup.insert(pMonster->GetCid());
				LogDebugFmtPrint("[logic] BrushGuide::InitGuideMonsGroup....nGroupId:%u,monsid:%u,cid:%llu, dupid:%u, sceneid:%u,stepidx:%d ", nGroupId, stMonCfg.m_id, pMonster->GetCid(), m_pDuplicate->GetDuplicateID(), m_pDuplicate->GetSceneID(), stepidx);
			}
		}
	}

}


//NPC死亡
void BrushGuide::NpcDie(SET_UINT32 &setNpc)
{
	if (nullptr == m_pDuplicate)
	{
		LogErrFmtPrint("BrushGuide::NpcDie...nullptr == m_pDuplicate...");
		return;
	}
	uint32_t sceneId = m_pDuplicate->GetSceneID();
	Scene *pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (nullptr == pScene)
	{
		LogErrFmtPrint("BrushGuide::NpcDie...nullptr == pScene...dupid:%u,scene:%u,mapid:%u,stepidx:%d ", m_pDuplicate->GetDuplicateID(), m_pDuplicate->GetSceneID(), m_pDuplicate->GetMapID(), m_pDuplicate->GetCurGuideIdx());
		return;
	}
	SET_UINT32::iterator iter = setNpc.begin();
	for (; iter != setNpc.end(); ++iter)
	{
		Npc *pNpc = pScene->GetNpcByCfgId((*iter));
		if (nullptr == pNpc)
		{
			continue;
		}
		if (pNpc->LeaveScene())
		{
			g_GetCreatureMgr()->WaitDestory(pNpc);
		}
	}
}
//NPC启用(可见，启动AI)
void BrushGuide::EnableNpc(SET_UINT32 &setNpc)
{
	if (nullptr == m_pDuplicate)
	{
		LogErrFmtPrint("BrushGuide::EnableNpc...nullptr == m_pDuplicate...");
		return;
	}
	uint32_t sceneId = m_pDuplicate->GetSceneID();
	Scene *pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (nullptr == pScene)
	{
		LogErrFmtPrint("BrushGuide::EnableNpc...nullptr == pScene...dupid:%u,scene:%u,mapid:%u,stepidx:%d ", m_pDuplicate->GetDuplicateID(), m_pDuplicate->GetSceneID(), m_pDuplicate->GetMapID(), m_pDuplicate->GetCurGuideIdx());
		return;
	}
	SET_UINT32::iterator iter = setNpc.begin();
	for (; iter != setNpc.end(); ++iter)
	{
		Npc *pNpc = pScene->GetNpcByCfgId((*iter));
		if (nullptr != pNpc)
		{
			//开启AI
			CreatureCommonAI *pAi = pNpc->GetAiData();
			if (nullptr != pAi)
			{
				pAi->SetAiEnable(true);
			}
			//设置可见
			pNpc->SetCanBeSeenFlag(true);
		}
	}
}
//NPC禁用(不可见，停止AI)
void BrushGuide::DisableNpc(SET_UINT32 &setNpc)
{
	if (nullptr == m_pDuplicate)
	{
		LogErrFmtPrint("BrushGuide::DisableNpc...nullptr == m_pDuplicate...");
		return;
	}
	uint32_t sceneId = m_pDuplicate->GetSceneID();
	Scene *pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (nullptr == pScene)
	{
		LogErrFmtPrint("BrushGuide::DisableNpc...nullptr == pScene...dupid:%u,scene:%u,mapid:%u,stepidx:%d ",m_pDuplicate->GetDuplicateID(),m_pDuplicate->GetSceneID(),m_pDuplicate->GetMapID(),m_pDuplicate->GetCurGuideIdx());
		return;
	}
	SET_UINT32::iterator iter = setNpc.begin();
	for (; iter != setNpc.end(); ++iter)
	{
		Npc *pNpc = pScene->GetNpcByCfgId((*iter));
		if (nullptr != pNpc)
		{
			//停止AI
			CreatureCommonAI *pAi = pNpc->GetAiData();
			if (nullptr != pAi)
			{
				pAi->StopAI();
			}
			pNpc->SetCanBeSeenFlag(false);
		}
	}
}